﻿namespace Microsoft.SharePoint.Client
{
    using Microsoft.SharePoint.Client.WebParts;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.IO;
    using System.Net;
    using System.Runtime.CompilerServices;

    [ScriptType("SP.File", ServerTypeId="{df28be1e-74b5-4b21-b73a-2bbac0a23d8a}")]
    public class File : ClientObject
    {
        [EditorBrowsable(EditorBrowsableState.Never)]
        public File(ClientRuntimeContext Context, ObjectPath ObjectPath) : base(Context, ObjectPath)
        {
        }

        [Remote]
        public void CheckIn(string comment, CheckinType checkInType)
        {
            if ((base.Context.ValidateOnClient && (comment != null)) && (comment.Length > 0x3ff))
            {
                throw ClientUtility.CreateArgumentException("comment");
            }
            ClientAction query = new ClientActionInvokeMethod(this, "CheckIn", new object[] { comment, checkInType });
            base.Context.AddQuery(query);
        }

        [Remote]
        public void CheckOut()
        {
            ClientAction query = new ClientActionInvokeMethod(this, "CheckOut", null);
            base.Context.AddQuery(query);
        }

        [Remote]
        public void CopyTo(string strNewUrl, bool bOverWrite)
        {
            if (base.Context.ValidateOnClient)
            {
                Uri uri;
                if (strNewUrl == null)
                {
                    throw ClientUtility.CreateArgumentNullException("strNewUrl");
                }
                if ((strNewUrl != null) && !Uri.TryCreate(strNewUrl, UriKind.RelativeOrAbsolute, out uri))
                {
                    throw ClientUtility.CreateArgumentException("strNewUrl");
                }
            }
            ClientAction query = new ClientActionInvokeMethod(this, "CopyTo", new object[] { strNewUrl, bOverWrite });
            base.Context.AddQuery(query);
        }

        [Remote]
        public void DeleteObject()
        {
            ClientAction query = new ClientActionInvokeMethod(this, "DeleteObject", null);
            base.Context.AddQuery(query);
            base.RemoveFromParentCollection();
        }

        [Remote]
        public LimitedWebPartManager GetLimitedWebPartManager(PersonalizationScope scope)
        {
            Dictionary<PersonalizationScope, LimitedWebPartManager> dictionary;
            object obj2;
            if (base.ObjectData.MethodReturnObjects.TryGetValue("GetLimitedWebPartManager", out obj2))
            {
                dictionary = (Dictionary<PersonalizationScope, LimitedWebPartManager>) obj2;
            }
            else
            {
                dictionary = new Dictionary<PersonalizationScope, LimitedWebPartManager>();
                base.ObjectData.MethodReturnObjects["GetLimitedWebPartManager"] = dictionary;
            }
            LimitedWebPartManager manager = null;
            if (!dictionary.TryGetValue(scope, out manager))
            {
                manager = new LimitedWebPartManager(base.Context, new ObjectPathMethod(base.Context, base.Path, "GetLimitedWebPartManager", new object[] { scope }));
                dictionary[scope] = manager;
            }
            return manager;
        }

        private static void GetResponseCallback(IAsyncResult asyncResult)
        {
            OpenBinaryAsyncState asyncState = asyncResult.AsyncState as OpenBinaryAsyncState;
            if (asyncState != null)
            {
                HttpWebResponse response = (HttpWebResponse) asyncState.HttpWebRequest.EndGetResponse(asyncResult);
                if (response.StatusCode != HttpStatusCode.OK)
                {
                    string message = Resources.GetString("RequestUnexpectedResponse", new object[] { response.ContentType, response.StatusCode });
                    if (asyncState.FailedCallback != null)
                    {
                        asyncState.FailedCallback(asyncState.HttpWebRequest, new OpenBinaryFailedEventArgs(response.StatusCode, message));
                    }
                }
                else
                {
                    Stream responseStream = response.GetResponseStream();
                    if (asyncState.SucceededCallback != null)
                    {
                        asyncState.SucceededCallback(asyncState.HttpWebRequest, new OpenBinarySucceededEventArgs(responseStream));
                    }
                }
            }
        }

        internal void InitFromCreationInformation(FileCreationInformation creation)
        {
            if (creation != null)
            {
                base.ObjectData.Properties["Name"] = creation.Url;
                if (!string.IsNullOrEmpty(creation.Url))
                {
                    if (creation.Url.EndsWith("/", StringComparison.Ordinal))
                    {
                        throw new ArgumentException();
                    }
                    int num = creation.Url.LastIndexOf('/');
                    if ((num >= 0) && (num < creation.Url.Length))
                    {
                        string str = creation.Url.Substring(num + 1);
                        base.ObjectData.Properties["Name"] = str;
                    }
                }
            }
        }

        protected override bool InitOnePropertyFromJson(string peekedName, JsonReader reader)
        {
            bool flag = base.InitOnePropertyFromJson(peekedName, reader);
            if (!flag)
            {
                switch (peekedName)
                {
                    case "Exists":
                        flag = true;
                        reader.ReadName();
                        base.ObjectData.Properties["Exists"] = reader.ReadBoolean();
                        return flag;

                    case "Title":
                        flag = true;
                        reader.ReadName();
                        base.ObjectData.Properties["Title"] = reader.ReadString();
                        return flag;

                    case "Author":
                        flag = true;
                        reader.ReadName();
                        this.Author.FromJson(reader);
                        return flag;

                    case "ModifiedBy":
                        flag = true;
                        reader.ReadName();
                        this.ModifiedBy.FromJson(reader);
                        return flag;

                    case "TimeCreated":
                        flag = true;
                        reader.ReadName();
                        base.ObjectData.Properties["TimeCreated"] = reader.ReadDateTime();
                        return flag;

                    case "TimeLastModified":
                        flag = true;
                        reader.ReadName();
                        base.ObjectData.Properties["TimeLastModified"] = reader.ReadDateTime();
                        return flag;

                    case "CustomizedPageStatus":
                        flag = true;
                        reader.ReadName();
                        base.ObjectData.Properties["CustomizedPageStatus"] = reader.ReadEnum<Microsoft.SharePoint.Client.CustomizedPageStatus>();
                        return flag;

                    case "ETag":
                        flag = true;
                        reader.ReadName();
                        base.ObjectData.Properties["ETag"] = reader.ReadString();
                        return flag;

                    case "LockedByUser":
                        flag = true;
                        reader.ReadName();
                        this.LockedByUser.FromJson(reader);
                        return flag;

                    case "CheckOutType":
                        flag = true;
                        reader.ReadName();
                        base.ObjectData.Properties["CheckOutType"] = reader.ReadEnum<Microsoft.SharePoint.Client.CheckOutType>();
                        return flag;

                    case "CheckedOutByUser":
                        flag = true;
                        reader.ReadName();
                        this.CheckedOutByUser.FromJson(reader);
                        return flag;

                    case "CheckInComment":
                        flag = true;
                        reader.ReadName();
                        base.ObjectData.Properties["CheckInComment"] = reader.ReadString();
                        return flag;

                    case "UIVersion":
                        flag = true;
                        reader.ReadName();
                        base.ObjectData.Properties["UIVersion"] = reader.ReadInt32();
                        return flag;

                    case "MajorVersion":
                        flag = true;
                        reader.ReadName();
                        base.ObjectData.Properties["MajorVersion"] = reader.ReadInt32();
                        return flag;

                    case "MinorVersion":
                        flag = true;
                        reader.ReadName();
                        base.ObjectData.Properties["MinorVersion"] = reader.ReadInt32();
                        return flag;

                    case "UIVersionLabel":
                        flag = true;
                        reader.ReadName();
                        base.ObjectData.Properties["UIVersionLabel"] = reader.ReadString();
                        return flag;

                    case "ServerRelativeUrl":
                        flag = true;
                        reader.ReadName();
                        base.ObjectData.Properties["ServerRelativeUrl"] = reader.ReadString();
                        return flag;

                    case "Name":
                        flag = true;
                        reader.ReadName();
                        base.ObjectData.Properties["Name"] = reader.ReadString();
                        return flag;

                    case "Versions":
                        flag = true;
                        reader.ReadName();
                        this.Versions.FromJson(reader);
                        return flag;

                    case "ListItemAllFields":
                        flag = true;
                        reader.ReadName();
                        this.ListItemAllFields.FromJson(reader);
                        return flag;

                    case "Level":
                        flag = true;
                        reader.ReadName();
                        base.ObjectData.Properties["Level"] = reader.ReadEnum<FileLevel>();
                        return flag;
                }
            }
            return flag;
        }

        private static string MakeFullUrl(ClientContext context, string serverRelativeUrl)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (serverRelativeUrl == null)
            {
                throw new ArgumentNullException("serverRelativeUrl");
            }
            if (!serverRelativeUrl.StartsWith("/"))
            {
                throw new ArgumentOutOfRangeException("serverRelativeUrl");
            }
            Uri baseUri = new Uri(context.Url);
            baseUri = new Uri(baseUri, serverRelativeUrl);
            return baseUri.AbsoluteUri;
        }

        [Remote]
        public void MoveTo(string newUrl, MoveOperations flags)
        {
            if (base.Context.ValidateOnClient)
            {
                Uri uri;
                if (newUrl == null)
                {
                    throw ClientUtility.CreateArgumentNullException("newUrl");
                }
                if ((newUrl != null) && !Uri.TryCreate(newUrl, UriKind.RelativeOrAbsolute, out uri))
                {
                    throw ClientUtility.CreateArgumentException("newUrl");
                }
            }
            ClientAction query = new ClientActionInvokeMethod(this, "MoveTo", new object[] { newUrl, flags });
            base.Context.AddQuery(query);
        }

        public static void OpenBinaryDirect(ClientContext context, string serverRelativeUrl, EventHandler<OpenBinarySucceededEventArgs> succeededCallback, EventHandler<OpenBinaryFailedEventArgs> failedCallback)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (context.HasPendingRequest)
            {
                throw new ClientRequestException(Resources.GetString("NoDirectHttpRequest"));
            }
            HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(new Uri(MakeFullUrl(context, serverRelativeUrl)));
            context.FireExecutingWebRequestEventInternal(new WebRequestEventArgs(webRequest));
            webRequest.Headers[HttpRequestHeader.Translate] = "f";
            webRequest.Method = "GET";
            OpenBinaryAsyncState state = new OpenBinaryAsyncState {
                SucceededCallback = succeededCallback,
                FailedCallback = failedCallback,
                HttpWebRequest = webRequest
            };
            webRequest.BeginGetResponse(new AsyncCallback(Microsoft.SharePoint.Client.File.GetResponseCallback), state);
        }

        [Remote]
        public void Publish(string comment)
        {
            if ((base.Context.ValidateOnClient && (comment != null)) && (comment.Length > 0x3ff))
            {
                throw ClientUtility.CreateArgumentException("comment");
            }
            ClientAction query = new ClientActionInvokeMethod(this, "Publish", new object[] { comment });
            base.Context.AddQuery(query);
        }

        [Remote]
        public ClientResult<Guid> Recycle()
        {
            ClientAction query = new ClientActionInvokeMethod(this, "Recycle", null);
            base.Context.AddQuery(query);
            ClientResult<Guid> result = new ClientResult<Guid>();
            base.Context.AddQueryIdAndResultObject(query.Id, result);
            base.RemoveFromParentCollection();
            return result;
        }

        [Remote]
        public void SaveBinary(FileSaveBinaryInformation parameters)
        {
            if (base.Context.ValidateOnClient)
            {
                if (parameters == null)
                {
                    throw ClientUtility.CreateArgumentNullException("parameters");
                }
                if (parameters != null)
                {
                    if (parameters.Content == null)
                    {
                        throw ClientUtility.CreateArgumentNullException("parameters.Content");
                    }
                    if ((parameters.Content != null) && (parameters.Content.Length == 0))
                    {
                        throw ClientUtility.CreateArgumentException("parameters.Content");
                    }
                }
            }
            ClientAction query = new ClientActionInvokeMethod(this, "SaveBinary", new object[] { parameters });
            base.Context.AddQuery(query);
        }

        [Remote]
        public void UndoCheckOut()
        {
            ClientAction query = new ClientActionInvokeMethod(this, "UndoCheckOut", null);
            base.Context.AddQuery(query);
        }

        [Remote]
        public void UnPublish(string comment)
        {
            if ((base.Context.ValidateOnClient && (comment != null)) && (comment.Length > 0x3ff))
            {
                throw ClientUtility.CreateArgumentException("comment");
            }
            ClientAction query = new ClientActionInvokeMethod(this, "UnPublish", new object[] { comment });
            base.Context.AddQuery(query);
        }

        [Remote]
        public User Author
        {
            get
            {
                object obj2;
                if (base.ObjectData.ClientObjectProperties.TryGetValue("Author", out obj2))
                {
                    return (User) obj2;
                }
                User user = new User(base.Context, new ObjectPathProperty(base.Context, base.Path, "Author"));
                base.ObjectData.ClientObjectProperties["Author"] = user;
                return user;
            }
        }

        [Remote]
        public User CheckedOutByUser
        {
            get
            {
                object obj2;
                if (base.ObjectData.ClientObjectProperties.TryGetValue("CheckedOutByUser", out obj2))
                {
                    return (User) obj2;
                }
                User user = new User(base.Context, new ObjectPathProperty(base.Context, base.Path, "CheckedOutByUser"));
                base.ObjectData.ClientObjectProperties["CheckedOutByUser"] = user;
                return user;
            }
        }

        [Remote]
        public string CheckInComment
        {
            get
            {
                base.CheckUninitializedProperty("CheckInComment");
                return (string) base.ObjectData.Properties["CheckInComment"];
            }
        }

        [Remote]
        public Microsoft.SharePoint.Client.CheckOutType CheckOutType
        {
            get
            {
                base.CheckUninitializedProperty("CheckOutType");
                return (Microsoft.SharePoint.Client.CheckOutType) base.ObjectData.Properties["CheckOutType"];
            }
        }

        [Remote]
        public Microsoft.SharePoint.Client.CustomizedPageStatus CustomizedPageStatus
        {
            get
            {
                base.CheckUninitializedProperty("CustomizedPageStatus");
                return (Microsoft.SharePoint.Client.CustomizedPageStatus) base.ObjectData.Properties["CustomizedPageStatus"];
            }
        }

        [Remote]
        public string ETag
        {
            get
            {
                base.CheckUninitializedProperty("ETag");
                return (string) base.ObjectData.Properties["ETag"];
            }
        }

        [Remote]
        public bool Exists
        {
            get
            {
                base.CheckUninitializedProperty("Exists");
                return (bool) base.ObjectData.Properties["Exists"];
            }
        }

        [Remote]
        public FileLevel Level
        {
            get
            {
                base.CheckUninitializedProperty("Level");
                return (FileLevel) base.ObjectData.Properties["Level"];
            }
        }

        [Remote]
        public ListItem ListItemAllFields
        {
            get
            {
                object obj2;
                if (base.ObjectData.ClientObjectProperties.TryGetValue("ListItemAllFields", out obj2))
                {
                    return (ListItem) obj2;
                }
                ListItem item = new ListItem(base.Context, new ObjectPathProperty(base.Context, base.Path, "ListItemAllFields"));
                base.ObjectData.ClientObjectProperties["ListItemAllFields"] = item;
                return item;
            }
        }

        [Remote]
        public User LockedByUser
        {
            get
            {
                object obj2;
                if (base.ObjectData.ClientObjectProperties.TryGetValue("LockedByUser", out obj2))
                {
                    return (User) obj2;
                }
                User user = new User(base.Context, new ObjectPathProperty(base.Context, base.Path, "LockedByUser"));
                base.ObjectData.ClientObjectProperties["LockedByUser"] = user;
                return user;
            }
        }

        [Remote]
        public int MajorVersion
        {
            get
            {
                base.CheckUninitializedProperty("MajorVersion");
                return (int) base.ObjectData.Properties["MajorVersion"];
            }
        }

        [Remote]
        public int MinorVersion
        {
            get
            {
                base.CheckUninitializedProperty("MinorVersion");
                return (int) base.ObjectData.Properties["MinorVersion"];
            }
        }

        [Remote]
        public User ModifiedBy
        {
            get
            {
                object obj2;
                if (base.ObjectData.ClientObjectProperties.TryGetValue("ModifiedBy", out obj2))
                {
                    return (User) obj2;
                }
                User user = new User(base.Context, new ObjectPathProperty(base.Context, base.Path, "ModifiedBy"));
                base.ObjectData.ClientObjectProperties["ModifiedBy"] = user;
                return user;
            }
        }

        [Remote]
        public string Name
        {
            get
            {
                base.CheckUninitializedProperty("Name");
                return (string) base.ObjectData.Properties["Name"];
            }
        }

        [Remote]
        public string ServerRelativeUrl
        {
            get
            {
                base.CheckUninitializedProperty("ServerRelativeUrl");
                return (string) base.ObjectData.Properties["ServerRelativeUrl"];
            }
        }

        [Remote]
        public DateTime TimeCreated
        {
            get
            {
                base.CheckUninitializedProperty("TimeCreated");
                return (DateTime) base.ObjectData.Properties["TimeCreated"];
            }
        }

        [Remote]
        public DateTime TimeLastModified
        {
            get
            {
                base.CheckUninitializedProperty("TimeLastModified");
                return (DateTime) base.ObjectData.Properties["TimeLastModified"];
            }
        }

        [Remote]
        public string Title
        {
            get
            {
                base.CheckUninitializedProperty("Title");
                return (string) base.ObjectData.Properties["Title"];
            }
        }

        [Remote]
        public int UIVersion
        {
            get
            {
                base.CheckUninitializedProperty("UIVersion");
                return (int) base.ObjectData.Properties["UIVersion"];
            }
        }

        [Remote]
        public string UIVersionLabel
        {
            get
            {
                base.CheckUninitializedProperty("UIVersionLabel");
                return (string) base.ObjectData.Properties["UIVersionLabel"];
            }
        }

        [Remote]
        public FileVersionCollection Versions
        {
            get
            {
                object obj2;
                if (base.ObjectData.ClientObjectProperties.TryGetValue("Versions", out obj2))
                {
                    return (FileVersionCollection) obj2;
                }
                FileVersionCollection versions = new FileVersionCollection(base.Context, new ObjectPathProperty(base.Context, base.Path, "Versions"));
                base.ObjectData.ClientObjectProperties["Versions"] = versions;
                return versions;
            }
        }

        private class OpenBinaryAsyncState
        {
            public EventHandler<OpenBinaryFailedEventArgs> FailedCallback { get; set; }

            public System.Net.HttpWebRequest HttpWebRequest { get; set; }

            public EventHandler<OpenBinarySucceededEventArgs> SucceededCallback { get; set; }
        }
    }
}

